import { Rectangle } from "../math";
import { Behaviour } from "./Behaviour";
import { GameEngine } from "./GameEngine";
import { AbstractRenderer } from "./AbstractRenderer";


export class GameObject {

    id: string = ''

    _active: boolean = false;

    get active() {
        return this._active;
    }

    set active(value: boolean) {
        this._active = value;
        for (const behaviour of this.behaviours) {
            if (behaviour.active !== value) {
                behaviour.active = value;
            }
        }
        for (const child of this.children) {
            child.active = value;
        }
    }

    static gameObjectStore: { [uuid: number]: GameObject } = {};

    engine: GameEngine;

    static get(uuid: number) {
        return GameObject.gameObjectStore[uuid];
    }

    behaviours: Behaviour[] = [];
    children: GameObject[] = [];

    onClick: Function;
    parent: GameObject | null = null;
    bounds: Rectangle = new Rectangle();
    renderer: AbstractRenderer;
    readonly uuid: number;
    name: string;
    constructor() {
        this.uuid = createUUID();
        this.name = 'GameObject' + this.uuid;
        GameObject.gameObjectStore[this.uuid] = this;
    }

    addChild(child: GameObject) {
        child.engine = this.engine;
        this.children.push(child);
        child.parent = this;

        if (this.active) {
            child.active = true;
        }

    }
    removeChild(child: GameObject) {
        const index = this.children.indexOf(child);
        if (index >= 0) {
            this.children.splice(index, 1);
            child.active = false;
        }
    }

    addBehaviour(behaviour: Behaviour) {
        this.behaviours.push(behaviour);
        behaviour.engine = this.engine;
        behaviour.gameObject = this;

        if (this.active) {
            behaviour.active = true;

        }
    }

    getBehaviour<T extends typeof Behaviour>(clz: T): InstanceType<T> {
        for (const behaviour of this.behaviours) {
            const b = behaviour as any;
            if ((behaviour as any).constructor === clz) {
                return behaviour as any;
            }
        }
        return null;
    }

    removeBehaviour(behaviour: Behaviour) {
        const index = this.behaviours.indexOf(behaviour);
        if (index >= 0) {
            this.behaviours.splice(index, 0);
            behaviour.active = false;
        }
    }
}


let uuIdIndex = 0;
function createUUID() {
    return uuIdIndex++;
}